package com.aiyan.edu.govern.gateway.admin.service;

import com.aiyan.edu.framework.domain.gateway.GwRoute;
import com.aiyan.edu.framework.domain.gateway.request.QueryRouteRequest;
import com.aiyan.edu.framework.domain.gateway.response.GatewayCode;
import com.aiyan.edu.framework.domain.gateway.response.GatewayResponseResult;
import com.aiyan.edu.framework.exception.ExceptionThrow;
import com.aiyan.edu.framework.model.response.CommonCode;
import com.aiyan.edu.framework.model.response.QueryResponseResult;
import com.aiyan.edu.framework.model.response.QueryResult;
import com.aiyan.edu.govern.gateway.admin.config.RabbitmqConfig;
import com.aiyan.edu.govern.gateway.admin.dao.RoutesRepository;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: zqzhou
 * @create: 2019/12/01 17:19
 **/
@Service
public class RoutesService {

    @Autowired
    RoutesRepository routesRepository;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RabbitTemplate rabbitTemplate;

    public GatewayResponseResult<GwRoute> save(GwRoute gwRoute) {
        if (gwRoute == null) {
            ExceptionThrow.out(CommonCode.FAIL);
        }

        GwRoute save = this.routesRepository.save(gwRoute);

        return new GatewayResponseResult<>(CommonCode.SUCCESS, save);
    }

    public QueryResponseResult<GwRoute> list(int page, int size, QueryRouteRequest queryRouteRequest) {

        if (queryRouteRequest == null) {
            queryRouteRequest = new QueryRouteRequest();
        }

        if (page <= 0) {
            page = 1;
        }
        page = page - 1;
        if (size <= 0) {
            size = 10;
        }

        GwRoute gwRoute = new GwRoute();
        if (StringUtils.isNotEmpty(queryRouteRequest.getRouteId())) {
            gwRoute.setRouteId(queryRouteRequest.getRouteId());
        }
        if (StringUtils.isNotEmpty(queryRouteRequest.getServiceId())) {
            gwRoute.setServiceId(queryRouteRequest.getServiceId());
        }
        if (null != queryRouteRequest.getEnabled()) {
            gwRoute.setEnabled(queryRouteRequest.getEnabled());
        }

        //定义条件对象Example
        Example<GwRoute> example = Example.of(gwRoute);

        Pageable pageable = PageRequest.of(page, size);
        Page<GwRoute> all = this.routesRepository.findAll(example, pageable);

        QueryResult queryResult = new QueryResult();
        queryResult.setList(all.getContent());
        queryResult.setTotal(all.getTotalElements());
        QueryResponseResult queryResponseResult = new QueryResponseResult(CommonCode.SUCCESS, queryResult);

        return queryResponseResult;
    }

    public GatewayResponseResult<GwRoute> post(String routeId) {
        GwRoute gwRoute = this.routesRepository.findByRouteId(routeId);
        if (null == gwRoute) {
            ExceptionThrow.out(GatewayCode.ROUTE_NOTFOUND);
        }

        // 这里把路由信息发布到Redis

        Map<String, Object> routeMap = new HashMap<>();
        routeMap.put("id", gwRoute.getRouteId());
        routeMap.put("uri", gwRoute.getUri());
        routeMap.put("order", gwRoute.getRouteOrder());
        routeMap.put("predicates", JSON.parseObject(gwRoute.getPredicates(), List.class));
        routeMap.put("filters", JSON.parseObject(gwRoute.getFilters(), List.class));

        String key = "gateway:routes";
        List<Map<String, Object>> routes = new ArrayList<>();
        routes.add(routeMap);
        this.stringRedisTemplate.boundValueOps(key).set(JSON.toJSONString(routes));

        // 设置完redis后，发消息通知网关更新
        Map<String, String> msg = new HashMap<>();
        msg.put("version", "v1.0");
        this.rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_GATEWAY_ROUTES_FANOUT, "", JSON.toJSONString(msg));

        return new GatewayResponseResult<>(CommonCode.SUCCESS, gwRoute);


    }
}
